package com.fulu.game.bi.service.impl.auth.config;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.fulu.game.bi.common.util.http.RequestUtils;
import com.fulu.game.bi.common.util.lang.StringUtils;
import com.fulu.game.bi.entity.vo.ExceptionCode;
import com.fulu.game.bi.entity.vo.Result;
import com.fulu.game.bi.entity.vo.auth.user.UserLoginDisplayVO;
import com.fulu.game.bi.service.impl.auth.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.filter.AccessControlFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

@Slf4j
public class BiTokenFilter extends AccessControlFilter {

    private TokenService tokenService;

    public void setTokenService(TokenService tokenService) {
        this.tokenService = tokenService;
    }


    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            return true;
        }
        String token = request.getHeader("token");
        String uri = request.getRequestURI();
        Map<String, String> parameterMap = RequestUtils.getParameterMap(request);

        log.info("uri: {}, paramMap: {}, token: {}", uri, parameterMap, token);

        if (StringUtils.isEmpty(token)) {
            log.info("客户端没有传递token");
            return false;
        }

        Map<String, Object> cacheMap = tokenService.getUserMapBy(token);
        if (CollectionUtil.isEmpty(cacheMap)) {
            log.info("token - {} 不存在，或者已经过期。", token);
            return false;
        }

        UserLoginDisplayVO currentUser = BeanUtil.mapToBean(cacheMap, UserLoginDisplayVO.class, true);
        ((BiSubject) SecurityUtils.getSubject()).setCurrentUser(currentUser);

        tokenService.refreshToken(token);

        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setContentType("application/json; charset=utf-8");
        httpResponse.setHeader("Access-Control-Allow-Origin", "*");
        try (PrintWriter out = httpResponse.getWriter()) {
            String data = JSONObject.toJSONString(Result.nologin().data(ExceptionCode.NOT_EXIST_USER_AUTH.toObject()));
            out.write(data);
        } catch (IOException e) {
            log.error("IO异常: ", e);
        }
        return false;
    }
}
